package com.sd.common.utils;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.net.ssl.*;
import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yxm
 * @date 2019/3/14 13:44:44
 */
@Component
public class JerseyUtil {
    private static final Logger logger = LoggerFactory.getLogger(JerseyUtil.class);

    private static ClientConfig config = new DefaultClientConfig();
    private static JerseyUtil jerseyUtil;

    @PostConstruct
    public void init() {
        jerseyUtil = this;
    }

    private static Client client = Client.create();

    static {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
            config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
                    new HTTPSProperties(new HostnameVerifier() {
                        @Override
                        public boolean verify(String s, SSLSession sslSession) {
                            return true;
                        }
                    }, context));
        } catch (Exception e) {
            logger.error("初始化静态代码块方法失败：" + e);
        }
    }

    /**
     * 获取应用token信息
     *
     * @param companyId
     * @param url
     * @param client_id
     * @param client_secret
     * @return String
     * 修改token获取方法（原理：利用redis并设置expire）。
     * 1.从redis中取token
     * 2.判断token是否为null，如果不是直接返回，如果token==null则走第三步
     * 3.调用环信后台接口重新获取token和失效时间expires
     * 4.将token保存到redis，并给其redis值设置失效时间expires
     */
    public static Map<String, String> getToken(String companyId, String url, String client_id, String client_secret) {
        long startTime = System.currentTimeMillis();
        logger.info("开始获取token：");
        logger.info("tokenUrl:" + url);
        logger.info("companyId = " + companyId + ",client_id = " + client_id + ", client_secret = " + client_secret);
        String token = null;
        Map<String, String> resultMap = new HashMap<String, String>();
        if (null != token && !"".equals(token)) {
            logger.info("从缓存中取出token，获取token结束");
            resultMap.put("result", "success");
            resultMap.put("imToken", token);
            return resultMap;
        } else {
            Client client = Client.create(config);
            String jsonStr = null;
            try {
                client.setConnectTimeout(8000);
                logger.info("setConnectTimeout:" + 8000);
                WebResource webResource = client.resource(url);
                jsonStr = webResource.entity("{\"grant_type\": \"client_credentials\",\"client_id\": \"" + client_id + "\",\"client_secret\": \"" + client_secret + "\"}").header("Content-Type", "application/json").post(String.class);
                JSONObject jsonObject = JSONObject.fromObject(jsonStr);
                token = jsonObject.get("access_token").toString();
                String expires = jsonObject.get("expires_in").toString();
                resultMap.put("result", "success");
                resultMap.put("imToken", token);
            } catch (Exception e) {
                logger.error("====获取token失败===" + e.getMessage());
                resultMap.put("result", "failed");
            } finally {
                long endTime = System.currentTimeMillis();
                client.destroy();
                logger.info("=========开始获取token结束=====耗时:" + (endTime - startTime) + "ms");
            }
            return resultMap;
        }

    }

    public static String getSuperToken(String url, String grantType, String userName, String passWord) {
        String superToken = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url + "/management/token");
            JSONObject json = new JSONObject();
            json.put("grant_type", grantType);
            json.put("username", userName);
            json.put("password", passWord);

            ClientResponse response = webResource.header("Content-Type", "application/json").entity(json.toString()).post(ClientResponse.class);

            String jsonStr = response.getEntity(String.class);
            int status = response.getStatus();
            logger.info("response : [ status : " + status + ", jsonStr : " + jsonStr + "]");
            JSONObject jsonObject = JSONObject.fromObject(jsonStr);
            superToken = jsonObject.get("access_token").toString();
        } catch (Exception e) {
            logger.error("获取超级管理员token失败", e);
        } finally {
            client.destroy();
        }
        return superToken;
    }

    public static String response(String url, String param) {
        String result = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url);

            ClientResponse response = webResource.header("Content-Type", "application/x-www-form-urlencoded").entity(param).post(ClientResponse.class);

            String jsonStr = response.getEntity(String.class);
            int status = response.getStatus();
            logger.info("response : [ status : " + status + ", jsonStr : " + jsonStr + "]");
            JSONObject jsonObject = JSONObject.fromObject(jsonStr);
            result = (String) jsonObject.get("message");
            System.out.println("------------打印结果result-----------" + result);
        } catch (Exception e) {
            logger.error("数据回传失败", e);
        } finally {
            client.destroy();
        }
        return result;
    }

    public static String responseJson(String url, String param) {
        String result = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url);

            ClientResponse response = webResource.header("Content-Type", "application/json").entity(param).post(ClientResponse.class);

            result = response.getEntity(String.class);
            int status = response.getStatus();
            logger.info("response : [ status : " + status + ", jsonStr : " + result + "]");
//            JSONObject jsonObject = JSONObject.fromObject(result);
        } catch (Exception e) {
            logger.error("数据回传失败", e);
        } finally {
            client.destroy();
        }
        return result;
    }

    public static String sendSmsByAB(String url, String param, String timeStamp, String extTransactionNo, String localTransactionNo,
                                     String operator, String serviceType, String errorCode, String errorMsg) {

        String result = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url);

            ClientResponse response = webResource.header("timeStamp", timeStamp)
                    .header("extTransactionNo", extTransactionNo)
                    .header("localTransactionNo", localTransactionNo)
                    .header("operator", operator)
                    .header("serviceType", serviceType)
                    .header("errorCode", errorCode)
                    .header("errorMsg", errorMsg)
                    .header("Content-Type", "application/json")
                    .entity(param).post(ClientResponse.class);

            String jsonStr = response.getEntity(String.class);

            int status = response.getStatus();

            logger.info("response : [ status : " + status + ", jsonStr : " + jsonStr + "]");

            //JSONObject jsonObject = JSONObject.fromObject(jsonStr);

            //result = (String)jsonObject.get("message");
            result = String.valueOf(status);

            System.out.println("------------打印结果result-----------" + result);

        } catch (Exception e) {

            logger.error("请求失败", e);

        } finally {

            client.destroy();
        }
        return result;
    }

    public static String sendSms(String url, String loginName, String password,
                                 String mobile, String message, String starttime,
                                 String searchID, String childUser) {
        String result = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url);

            MultivaluedMap queryParams = new MultivaluedMapImpl();
            queryParams.add("login_name", loginName);
            queryParams.add("password", password);
            queryParams.add("mobile", mobile);
            queryParams.add("message", message);
            queryParams.add("start_time", starttime);
            queryParams.add("Search_ID", searchID);
            queryParams.add("childUser", childUser);

            ClientResponse response = webResource.header("Content-Type", "application/x-www-form-urlencoded").entity(queryParams).post(ClientResponse.class);

            String jsonStr = response.getEntity(String.class);
            int status = response.getStatus();

            JAXBContext jc = JAXBContext.newInstance(String.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StreamSource xmlSource = new StreamSource(new StringReader(jsonStr));
            JAXBElement<String> je = unmarshaller.unmarshal(xmlSource, String.class);
            String sendMessage = je.getValue();
            System.out.println("发送结果是:" + sendMessage);

            logger.info("response : [ status : " + status + ", sendMessage : " + sendMessage + "]");
            result = sendMessage;
        } catch (Exception e) {
            logger.error("发送失败", e);
        } finally {
            client.destroy();
        }
        return result;
    }

    public static String sendSmsFuture(String url, String param) {
        String result = "";

        Client client = Client.create(config);
        try {
            WebResource webResource = client.resource(url);

            ClientResponse response = webResource.header("Content-Type", "application/json").entity(param).post(ClientResponse.class);

            String jsonStr = response.getEntity(String.class);

            int status = response.getStatus();

            logger.info("response : [ status : " + status + ", jsonStr : " + jsonStr + "]");

            JSONObject jsonObject = JSONObject.fromObject(jsonStr);

            result = (String) jsonObject.get("respCode");

            System.out.println("------------打印结果result-----------" + result);

        } catch (Exception e) {
            logger.error("发送失败", e);
        } finally {
            client.destroy();
        }
        return result;
    }


    public static void main(String[] args) {

        String mobile = "13261706943";

        String url = "http://139.224.148.37:19082/sms/sd";

        String loginName = "piccsdjf";

        String password = "piccSDjf3700";

        String message = "尊敬的客户:您好!请注册【山东人保财险】公众号,在【享服务】中预约年审服务，可以咨询在线客服或者拨打95518，了解更多服务内容。";

        String starttime = "2020-06-08 18:31:00";

        String searchID = "201932007115720";

        String childUser = "37010000";

        String result = sendSms(url, loginName, password, mobile, message, starttime, searchID, childUser);

        System.out.println("发送结果是:" + result);
    }


}
